const FtpSrv = require('ftp-srv');
const path = require('path');
const fs = require('fs-extra');
const logger = require('../config/logger');
const db = require('../config/database');

class FTPServer {
  constructor() {
    this.server = null;
    this.uploadDir = process.env.UPLOAD_DIR || './uploads';
    this.socketManager = null; // WebSocket管理器
    this.activeConnections = new Map(); // 活动连接
    this.activeTransfers = new Map(); // 活动传输
  }

  /**
   * 设置WebSocket管理器
   */
  setSocketManager(socketManager) {
    this.socketManager = socketManager;
    logger.info('FTP服务器已连接到WebSocket管理器');
  }

  /**
   * 启动FTP服务器
   */
  async start() {
    const ftpPort = process.env.FTP_PORT || 21;
    const ftpHost = process.env.FTP_HOST || '0.0.0.0';
    const passivePortRange = process.env.FTP_PASSIVE_PORT_RANGE || '30000-31000';

    this.server = new FtpSrv({
      url: `ftp://${ftpHost}:${ftpPort}`,
      pasv_url: process.env.FTP_PASV_URL || '127.0.0.1',
      pasv_min: parseInt(passivePortRange.split('-')[0]),
      pasv_max: parseInt(passivePortRange.split('-')[1]),
      greeting: '欢迎使用文件同步器FTP服务',
      anonymous: false
    });

    // 登录验证
    this.server.on('login', async ({ connection, username, password }, resolve, reject) => {
      try {
        logger.info(`FTP登录尝试: ${username}`);

        // 使用固定的FTP账户验证
        const ftpUser = process.env.FTP_USER || 'ftpuser';
        const ftpPassword = process.env.FTP_PASSWORD || 'ftppassword123';

        if (username !== ftpUser || password !== ftpPassword) {
          logger.warn(`FTP登录失败: 固定账户验证失败 - ${username}`);
          return reject(new Error('用户名或密码错误'));
        }

        // 设置共享的根目录（所有客户端共享）
        const sharedRoot = path.join(this.uploadDir, 'shared');
        await fs.ensureDir(sharedRoot);

        logger.info(`FTP登录成功: ${username} (固定账户)`);

        // 设置连接参数
        connection.ftpUser = username;

        // 记录活动连接
        this.activeConnections.set(connection.id, {
          ftpUser: username,
          ip: connection.ip,
          connectedAt: new Date()
        });

        // 记录系统日志
        await db.query(
          `INSERT INTO system_logs (user_type, user_id, level, action, content, ip_address)
           VALUES ('system', 0, 'info', 'ftp_login', ?, ?)`,
          [`FTP登录成功: ${username} (固定账户)`, connection.ip]
        );

        resolve({ root: sharedRoot, cwd: '/' });
      } catch (error) {
        logger.error('FTP登录错误:', error);
        reject(new Error('登录失败'));
      }
    });

    // 文件上传开始事件
    this.server.on('STOR', async (error, { connection, path: filePath }) => {
      if (error) {
        logger.error(`FTP上传失败: ${filePath}`, error);
        return;
      }

      try {
        const fileName = path.basename(filePath);
        const stats = await fs.stat(filePath);

        // 计算文件MD5
        const crypto = require('crypto');
        const hash = crypto.createHash('md5');
        const stream = fs.createReadStream(filePath);
        
        await new Promise((resolve, reject) => {
          stream.on('data', data => hash.update(data));
          stream.on('end', resolve);
          stream.on('error', reject);
        });

        const fileHash = hash.digest('hex');

        // 获取相对路径
        const sharedRoot = path.join(this.uploadDir, 'shared');
        const relativePath = path.relative(sharedRoot, filePath).replace(/\\/g, '/');

        // 插入数据库记录（使用system用户ID 0）
        const [result] = await db.query(
          `INSERT INTO files (file_name, file_path, file_size, file_hash, user_id, is_directory)
           VALUES (?, ?, ?, ?, 0, 0)
           ON DUPLICATE KEY UPDATE file_size = ?, updated_at = NOW()`,
          [fileName, `/${relativePath}`, stats.size, fileHash, stats.size]
        );

        // 记录系统日志
        await db.query(
          `INSERT INTO system_logs (user_type, user_id, level, action, content, ip_address)
           VALUES ('system', 0, 'info', 'file_upload', ?, ?)`,
          [`FTP上传文件: ${fileName} (${stats.size} bytes)`, connection.ip]
        );

        logger.info(`FTP上传成功: ${fileName} (固定账户, 大小: ${stats.size})`);
      } catch (error) {
        logger.error('FTP上传后处理失败:', error);
      }
    });

    // 文件下载事件
    this.server.on('RETR', async (error, { connection, path: filePath }) => {
      if (error) {
        logger.error(`FTP下载失败: ${filePath}`, error);
        return;
      }

      try {
        const fileName = path.basename(filePath);

        logger.info(`FTP下载: ${filePath} (固定账户)`);

        // 记录下载日志
        await db.query(
          `INSERT INTO system_logs (user_type, user_id, level, action, content, ip_address)
           VALUES ('system', 0, 'info', 'file_download', ?, ?)`,
          [`FTP下载文件: ${fileName}`, connection.ip]
        );
      } catch (error) {
        logger.error('FTP下载日志记录失败:', error);
      }
    });

    // 连接关闭事件
    this.server.on('disconnect', async ({ connection }) => {
      if (connection.ftpUser) {
        try {
          // 移除活动连接记录
          this.activeConnections.delete(connection.id);

          // 记录系统日志
          await db.query(
            `INSERT INTO system_logs (user_type, user_id, level, action, content, ip_address)
             VALUES ('system', 0, 'info', 'ftp_logout', ?, ?)`,
            [`FTP断开连接: ${connection.ftpUser} (固定账户)`, connection.ip]
          );

          logger.info(`FTP断开连接: ${connection.ftpUser} (固定账户)`);
        } catch (error) {
          logger.error('FTP断开连接处理失败:', error);
        }
      }
    });

    // 启动服务器
    await this.server.listen();
    logger.info(`FTP服务器已启动: ftp://${ftpHost}:${ftpPort}`);
    console.log(`
╔═══════════════════════════════════════════════════════╗
║   📁 FTP服务器已启动                                   ║
║   地址: ftp://${ftpHost}:${ftpPort}                    ║
║   被动模式端口: ${passivePortRange}                    ║
╚═══════════════════════════════════════════════════════╝
    `);
  }

  /**
   * 停止FTP服务器
   */
  async stop() {
    if (this.server) {
      await this.server.close();
      logger.info('FTP服务器已停止');
    }
  }

  /**
   * 获取FTP服务器状态
   */
  getStatus() {
    return {
      isRunning: this.server !== null,
      activeConnections: this.activeConnections.size,
      activeTransfers: this.activeTransfers.size,
      connections: Array.from(this.activeConnections.values())
    };
  }

  /**
   * 获取活动连接列表
   */
  getActiveConnections() {
    return Array.from(this.activeConnections.values());
  }

  /**
   * 断开指定用户的FTP连接
   */
  async disconnectUser(userId) {
    for (const [connectionId, connection] of this.activeConnections.entries()) {
      if (connection.userId === userId) {
        this.activeConnections.delete(connectionId);
        logger.info(`强制断开用户FTP连接: ${connection.username}`);
      }
    }
  }
}

module.exports = new FTPServer();
